//Natan
package xml;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import xml.elements.Uid;
import xml.others.FacadeConstructorUID;
import xml.others.IdManager;
import xml.uidElements.AbstractState;
import xml.uidElements.InitialState;
import xml.uidElements.PosCondition;
import xml.uidElements.PreCondition;
import xml.uidElements.State;
import xml.uidElements.Text;
import xml.uidElements.TextualNote;
import xml.uidElements.Transition;
import xml.uidElements.TransitionFromSet;
import xml.uidElements.UID;
import xml.uidElements.UIDCall;
import xml.uidElements.entry.DataEntry;
import xml.uidElements.entry.DataItem;
import xml.uidElements.entry.DataItemSet;
import xml.uidElements.entry.EnumeratedData;
import xml.uidElements.entry.EnumeratedOption;
import xml.uidElements.entry.ORDataEntry;
import xml.uidElements.entry.OptionalDataItem;
import xml.uidElements.entry.Structure;
import xml.uidElements.entry.StructureSet;
import xml.uidElements.entry.SubState;
import xml.uidElements.entry.XORDataEntry;
import xml.uidElements.output.DataOutput;
import xml.uidElements.output.OutputDataItem;
import xml.uidElements.output.OutputDataItemSet;
import xml.uidElements.output.OutputStructure;
import xml.uidElements.output.OutputStructureSet;

import com.thoughtworks.xstream.XStream;

//Eu coloquei isto:

public class ConverterToUidXml {

	/**
	 * @param args
	 * @throws IOException
	 */
	public static void main(String[] args) {
		try {
			// if (args.length == 1) {
			// //
			//
			// ConverterToUidXml converter = new ConverterToUidXml();
			// converter.convert(args[0], args[0].replaceAll(".xuid", ".xmi"));

			// } else if (args.length == 2) {
			//

			ConverterToUidXml converter = new ConverterToUidXml();
			converter.convert(args[0], args[1], args[2]);

			// } else if (args.length == 0 || args.length == 3) {
			// //
			//
			// boolean exit = false;
			// while (!exit) {
			// String str = "";
			// System.out.println("Entre com o nome do arquivo.");
			// InputStreamReader isr = new InputStreamReader(System.in);
			// BufferedReader br = new BufferedReader(isr);
			// try {
			// str = "src\\testFiles\\" + br.readLine();
			// if (!str.contains(".xuid")) {
			// str += ".xuid";
			// }
			// } catch (Exception e) {
			// e.printStackTrace();
			// continue;
			// }
			// str =
			// "\\Desenvolvimento\\Workspace\\WSEclipse\\UID-Converter-New\\"
			// + str;
			// ConverterToUidXml converter = new ConverterToUidXml();
			// converter.convert(str, str.replaceAll(".xuid", ".xmi"));
			// exit = true;
			// }
			// }
		} catch (Exception e) {
			System.out.println(e.getMessage());
			e.printStackTrace();
		}
	}

	public ConverterToUidXml() {

	}

	@Deprecated
	public void convert(String fileInput, String fileOutput) throws IOException {

	}

	public void convert(String fileInput, String fileOutput, String fileInputBKP)
			throws IOException {

		// System.out.println(fileInput);

		long startTime = System.currentTimeMillis();

		Uid uid = deserialize(fileInput);

		if (new File(fileInputBKP).exists()) {
			Uid uidBKP = deserialize(fileInputBKP);
			clean(uid, uidBKP);
		}

		bkp(fileInput, fileInputBKP);

		uid.setId(fileInput);

		// new IdManager().setValidIdsAndFindIdInitialState(d);
		IdManager.getInstance().setValidIdsAndFindIdInitialState(uid);

		String idUID = fileInput.substring(fileInput.lastIndexOf("\\") + 1,
				fileInput.lastIndexOf("."));
		new FactoryUID(idUID, idUID).insertElementsOfUid(uid);

		// d.

		serialize(fileOutput, FacadeConstructorUID.getInstance());

		FacadeConstructorUID.removeInstance();
		IdManager.removeInstance();

		long endTime = System.currentTimeMillis();

		System.out.println("ConverterToUidXml executed in "
				+ ((float) (endTime - startTime) / 1000) + "s");
	}

	@SuppressWarnings("unchecked")
	public Uid deserialize(String urlxml) {
		Uid d = null;
		try {
			JAXBContext context;
			context = JAXBContext.newInstance("xml.elements");
			Unmarshaller unmarshaller = context.createUnmarshaller();
			JAXBElement<Uid> element = (JAXBElement<Uid>) unmarshaller
					.unmarshal(new File(urlxml));
			d = element.getValue();
		} catch (JAXBException e) {
			System.out.println(e);
			e.printStackTrace();
		}
		return d;

	}

	public void serialize(String fileOutput, FacadeConstructorUID u)
			throws UnsupportedEncodingException {

		XStream xstream = new XStream();

		defineAliases(xstream);

		try {
			OutputStreamWriter saida = new OutputStreamWriter(
					new FileOutputStream(fileOutput), "UTF-8");
			// saida.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
			saida.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
			// saida.println("<!DOCTYPE UID-set SYSTEM 'file:./uid-2-0.dtd'>");
			// saida.append("<!DOCTYPE UID-set SYSTEM 'file:./uid-2-0.dtd'>");
			// saida.println("<xmi:XMI xmi:version=\"2.0\" xmlns:xmi=\"http://www.omg.org/XMI\" xmlns=\"CIM\">");
			saida.append("<xmi:XMI xmi:version=\"2.0\" xmlns:xmi=\"http://www.omg.org/XMI\" xmlns=\"CIM\">");
			xstream.toXML(u, saida);
			// saida.
			// saida.print("\n</xmi:XMI>");
			saida.append("\n</xmi:XMI>");
			saida.close();

			// xstream.

		} catch (Exception e) {
			System.out.println(e);
			e.printStackTrace();
		}

	}

	private void bkp(String fileInput, String fileInputBKP) throws IOException {
		byte[] input = Files.readAllBytes(Paths.get(fileInput));
		Files.write(Paths.get(fileInputBKP), input);
	}

	private void clean(Uid newUID, Uid bkpUID) {
		Map<Class<? extends Object>, List<String>> elementsMap = new HashMap<Class<? extends Object>, List<String>>();
		elementsMap.put(xml.elements.State.class, new ArrayList<String>());
		elementsMap.put(xml.elements.InitialState.class,
				new ArrayList<String>());
		elementsMap.put(xml.elements.Transition.class, new ArrayList<String>());
		elementsMap.put(xml.elements.UidCall.class, new ArrayList<String>());
		elementsMap.put(xml.elements.Condition.class, new ArrayList<String>());
		elementsMap.put(xml.elements.Note.class, new ArrayList<String>());
		elementsMap.put(xml.elements.Point.class, new ArrayList<String>());
		elementsMap.put(xml.elements.InitialTransition.class,
				new ArrayList<String>());

		elementsMap.put(xml.elements.Text.class, new ArrayList<String>());
		elementsMap.put(xml.elements.Output.class, new ArrayList<String>());
		elementsMap.put(xml.elements.Input.class, new ArrayList<String>());

		// pega todos os href dos elementos do bkpUID
		for (Object stateOrInitialStateOrTransition : bkpUID
				.getStatesOrInitialStateOrTransitions()) {
			if (stateOrInitialStateOrTransition instanceof xml.elements.State) {
				putState(elementsMap,
						(xml.elements.State) stateOrInitialStateOrTransition);
			} else if (stateOrInitialStateOrTransition instanceof xml.elements.InitialState) {
				putInitialState(
						elementsMap,
						(xml.elements.InitialState) stateOrInitialStateOrTransition);
			} else if (stateOrInitialStateOrTransition instanceof xml.elements.Transition) {
				putTransition(
						elementsMap,
						(xml.elements.Transition) stateOrInitialStateOrTransition);
			}
		}

		// varre ao contrário para retirar todos os elementos do newUID
		List<Object> statesOrInitialStateOrTransitions = newUID
				.getStatesOrInitialStateOrTransitions();
		for (int i = statesOrInitialStateOrTransitions.size() - 1; i >= 0; i--) {
			Object stateOrInitialStateOrTransition = statesOrInitialStateOrTransitions
					.get(i);
			if (stateOrInitialStateOrTransition instanceof xml.elements.State) {
				cleanState(elementsMap,
						(xml.elements.State) stateOrInitialStateOrTransition);
			} else if (stateOrInitialStateOrTransition instanceof xml.elements.InitialState) {
				cleanInitialState(
						elementsMap,
						(xml.elements.InitialState) stateOrInitialStateOrTransition);
			} else if (stateOrInitialStateOrTransition instanceof xml.elements.Transition) {
				cleanTransition(
						elementsMap,
						statesOrInitialStateOrTransitions,
						(xml.elements.Transition) stateOrInitialStateOrTransition);
			}
		}

	}

	private void cleanState(
			Map<Class<? extends Object>, List<String>> elementsMap,
			xml.elements.State state) {
		List<Object> listElements = state.getInputsOrOutputsOrTexts();
		for (int i = listElements.size() - 1; i >= 0; i--) {
			Object element = listElements.get(i);
			if (element instanceof xml.elements.Text) {
				if (elementsMap.get(xml.elements.Text.class).contains(
						((xml.elements.Text) element).getId())) {
					listElements.remove(element);
				}
			} else if (element instanceof xml.elements.SubState) {
				cleanSubState(elementsMap, (xml.elements.SubState) element);
			} else if (element instanceof xml.elements.Output) {
						if (elementsMap.get(xml.elements.Output.class).contains(
								((xml.elements.Output) element).getName())) {
							listElements.remove(element);
						}
			} else if (element instanceof xml.elements.Input) {
				if (elementsMap.get(xml.elements.Input.class).contains(
						((xml.elements.Input) element).getName())) {
					listElements.remove(element);
				}
			}
		}
	}

	private void cleanSubState(
			Map<Class<? extends Object>, List<String>> elementsMap,
			xml.elements.SubState subState) {
		List<Object> listElements = subState.getInputsOrOutputsOrTexts();
		for (int i = listElements.size() - 1; i >= 0; i--) {
			Object element = listElements.get(i);
			if (element instanceof xml.elements.Text) {
				if (elementsMap.get(xml.elements.Text.class).contains(
						((xml.elements.Text) element).getId())) {
					listElements.remove(element);
				}
			} else if (element instanceof xml.elements.SubState) {
				cleanSubState(elementsMap, (xml.elements.SubState) element);
			} else if (element instanceof xml.elements.Output) {
				if (elementsMap.get(xml.elements.Output.class).contains(
						((xml.elements.Output) element).getName())) {
					listElements.remove(element);
				}
			} else if (element instanceof xml.elements.Input) {
				if (elementsMap.get(xml.elements.Input.class).contains(
						((xml.elements.Input) element).getName())) {
					listElements.remove(element);
				}
			}
		}
	}

	private void cleanInitialState(
			Map<Class<? extends Object>, List<String>> elementsMap,
			xml.elements.InitialState state) {
		cleanState(elementsMap, state);
	}

	private void cleanTransition(
			Map<Class<? extends Object>, List<String>> elementsMap,
			List<Object> statesOrInitialStateOrTransitions,
			xml.elements.Transition transition) {
		if (elementsMap.get(xml.elements.Transition.class).contains(
				((xml.elements.Transition) transition).getId())) {
			statesOrInitialStateOrTransitions.remove(transition);
		}
	}

	private void putState(
			Map<Class<? extends Object>, List<String>> elementsMap,
			xml.elements.State state) {
		for (Object stateElement : state.getInputsOrOutputsOrTexts()) {
			if (stateElement instanceof xml.elements.Text) {
				elementsMap.get(xml.elements.Text.class).add(
						((xml.elements.Text) stateElement).getId());
			} else if (stateElement instanceof xml.elements.SubState) {
				putSubState(elementsMap, (xml.elements.SubState) stateElement);
			} else if (stateElement instanceof xml.elements.Output) {
				elementsMap.get(xml.elements.Output.class).add(
						((xml.elements.Output) stateElement).getName());
			} else if (stateElement instanceof xml.elements.Input) {
				elementsMap.get(xml.elements.Input.class).add(
						((xml.elements.Input) stateElement).getName());
			}
		}
	}

	private void putSubState(
			Map<Class<? extends Object>, List<String>> elementsMap,
			xml.elements.SubState subState) {
		for (Object stateElement : subState.getInputsOrOutputsOrTexts()) {
			if (stateElement instanceof xml.elements.Text) {
				elementsMap.get(xml.elements.Text.class).add(
						((xml.elements.Text) stateElement).getId());
			} else if (stateElement instanceof xml.elements.SubState) {
				putSubState(elementsMap, (xml.elements.SubState) stateElement);
			} else if (stateElement instanceof xml.elements.Output) {
				elementsMap.get(xml.elements.Output.class).add(
						((xml.elements.Output) stateElement).getName());
			} else if (stateElement instanceof xml.elements.Input) {
				elementsMap.get(xml.elements.Input.class).add(
						((xml.elements.Input) stateElement).getName());
			}
		}
	}

	private void putInitialState(
			Map<Class<? extends Object>, List<String>> elementsMap,
			xml.elements.InitialState initialState) {
		putState(elementsMap, initialState);
	}

	private void putTransition(
			Map<Class<? extends Object>, List<String>> elementsMap,
			xml.elements.Transition transition) {
		elementsMap.get(xml.elements.Transition.class)
				.add(transition.getId());
	}

	private void defineAliases(XStream xstream) {
		// xstream.alias("UID-set", FacadeConstructorUID.class);
		xstream.alias("UIDset", FacadeConstructorUID.class);
		xstream.alias("UID", UID.class);
		xstream.alias("state", State.class);
		xstream.alias("substate", SubState.class);
		// xstream.alias("initial-state", InitialState.class);
		xstream.alias("initialstate", InitialState.class);

		// Eu coloquei este:
		// xstream.alias("UID-call", UidCall.class);
		xstream.alias("UIDcall", UIDCall.class);

		// xstream.alias("pre-condition", PreCondition.class);
		xstream.alias("precondition", PreCondition.class);
		// xstream.alias("pos-condition", PosCondition.class);
		xstream.alias("poscondition", PosCondition.class);
		// xstream.alias("textual-note", TextualNote.class);
		xstream.alias("textualnote", TextualNote.class);
		xstream.alias("transition", Transition.class);
		// xstream.alias("transition-from-set", TransitionFromSet.class);
		xstream.alias("transitionfromset", TransitionFromSet.class);

		// xstream.alias("data-entry", DataEntry.class);
		xstream.alias("dataentry", DataEntry.class);
		// xstream.alias("data-output", DataOutput.class);
		xstream.alias("dataoutput", DataOutput.class);

		// xstream.alias("data-item", DataItem.class);
		xstream.alias("dataitem", DataItem.class);
		// xstream.alias("data-item-set", DataItemSet.class);
		xstream.alias("dataitemset", DataItemSet.class);

		// xstream.alias("optional-data-item", OptionalDataItem.class);
		xstream.alias("optionaldataitem", OptionalDataItem.class);

		// xstream.alias("enumerated-data", EnumeratedData.class);
		xstream.alias("enumerateddata", EnumeratedData.class);
		// xstream.alias("enumerated-option", EnumeratedOption.class);
		xstream.alias("enumeratedoption", EnumeratedOption.class);

		// xstream.alias("OR-data-entry", ORDataEntry.class);
		xstream.alias("ORdataentry", ORDataEntry.class);
		// xstream.alias("XOR-data-entry", XORDataEntry.class);
		xstream.alias("XORdataentry", XORDataEntry.class);

		// xstream.alias("output-data-item", OutputDataItem.class);
		xstream.alias("outputdataitem", OutputDataItem.class);
		// xstream.alias("output-data-item-set", OutputDataItemSet.class);
		xstream.alias("outputdataitemset", OutputDataItemSet.class);

		xstream.alias("structure", Structure.class);
		// xstream.alias("structure-set", StructureSet.class);
		xstream.alias("structureset", StructureSet.class);

		// xstream.alias("output-structure", OutputStructure.class);
		xstream.alias("outputstructure", OutputStructure.class);
		// xstream.alias("output-structure-set", OutputStructureSet.class);
		xstream.alias("outputstructureset", OutputStructureSet.class);

		xstream.alias("text", Text.class);

		// xstream.aliasField("initial-state", UID.class, "initialState");
		xstream.aliasField("initialstate", UID.class, "initialState");
		// xstream.aliasField("input-structure-elements", Structure.class,
		// "listDataItemsAndStructures");
		xstream.aliasField("inputstructureelements", Structure.class,
				"listDataItemsAndStructures");
		// xstream.aliasField("data-item", OptionalDataItem.class, "dataItem");
		xstream.aliasField("dataitem", OptionalDataItem.class, "dataItem");
		// xstream.aliasField("data-item", DataItemSet.class, "dataItem");
		xstream.aliasField("dataitem", DataItemSet.class, "dataItem");
		// xstream.aliasField("min-cardinality", DataItemSet.class,
		// "cardinalityMin");
		xstream.aliasField("mincardinality", DataItemSet.class,
				"cardinalityMin");
		// xstream.aliasField("max-cardinality", DataItemSet.class,
		// "cardinalityMax");
		xstream.aliasField("maxcardinality", DataItemSet.class,
				"cardinalityMax");
		// xstream.aliasField("min-cardinality", StructureSet.class,
		// "cardinalityMin");
		xstream.aliasField("mincardinality", StructureSet.class,
				"cardinalityMin");
		// xstream.aliasField("max-cardinality", StructureSet.class,
		// "cardinalityMax");
		xstream.aliasField("maxcardinality", StructureSet.class,
				"cardinalityMax");
		// xstream.aliasField("min-cardinality", OutputDataItemSet.class,
		// "cardinalityMin");
		xstream.aliasField("mincardinality", OutputDataItemSet.class,
				"cardinalityMin");
		// xstream.aliasField("max-cardinality", OutputDataItemSet.class,
		// "cardinalityMax");
		xstream.aliasField("maxcardinality", OutputDataItemSet.class,
				"cardinalityMax");
		// xstream.aliasField("output-data-item", OutputDataItemSet.class,
		// "dataItem");
		xstream.aliasField("outputdataitem", OutputDataItemSet.class,
				"dataItem");
		// xstream.aliasField("min-cardinality", OutputStructureSet.class,
		// "cardinalityMin");
		xstream.aliasField("mincardinality", OutputStructureSet.class,
				"cardinalityMin");
		// xstream.aliasField("max-cardinality", OutputStructureSet.class,
		// "cardinalityMax");
		xstream.aliasField("maxcardinality", OutputStructureSet.class,
				"cardinalityMax");
		// xstream.aliasField("min-selection", EnumeratedData.class,
		// "cardinalityMin");
		xstream.aliasField("minselection", EnumeratedData.class,
				"cardinalityMin");
		// xstream.aliasField("max-selection", EnumeratedData.class,
		// "cardinalityMax");
		xstream.aliasField("maxselection", EnumeratedData.class,
				"cardinalityMax");

		// xstream.aliasField("data-item", ORDataEntry.class, "dataItem1");
		// xstream.aliasField("data-item", ORDataEntry.class, "dataItem2");
		// xstream.aliasField("data-item", XORDataEntry.class, "dataItem1");
		// xstream.aliasField("data-item", XORDataEntry.class, "dataItem2");
		xstream.aliasField("dataitem", ORDataEntry.class, "dataItem1");
		xstream.aliasField("dataitem", ORDataEntry.class, "dataItem2");
		xstream.aliasField("dataitem", XORDataEntry.class, "dataItem1");
		xstream.aliasField("dataitem", XORDataEntry.class, "dataItem2");

		// xstream.aliasField("output-structure-elements",
		// OutputStructure.class,
		// "listDataItemsAndStructures");
		xstream.aliasField("outputstructureelements", OutputStructure.class,
				"listDataItemsAndStructures");
		// xstream.aliasField("output-structure-elements",
		// OutputStructureSet.class, "listDataItemsAndStructures");
		xstream.aliasField("outputstructureelements", OutputStructureSet.class,
				"listDataItemsAndStructures");

		// xstream.aliasField("target-type", Transition.class, "targetType");
		xstream.aliasField("targettype", Transition.class, "targetType");
		// xstream.aliasField("no-return", Transition.class, "noReturn");
		xstream.aliasField("noreturn", Transition.class, "noReturn");

		xstream.useAttributeFor(UID.class, "id");
		xstream.useAttributeFor(UID.class, "name");
		xstream.useAttributeFor(AbstractState.class, "id");
		xstream.useAttributeFor(PosCondition.class, "condition");
		xstream.useAttributeFor(PreCondition.class, "condition");
		xstream.useAttributeFor(TextualNote.class, "note");

		// Eu coloquei estes dois:
		xstream.useAttributeFor(UIDCall.class, "id");
		xstream.useAttributeFor(UIDCall.class, "name");

		xstream.useAttributeFor(DataItem.class, "id");
		xstream.useAttributeFor(DataItem.class, "name");
		xstream.useAttributeFor(DataItem.class, "domain");
		xstream.useAttributeFor(DataItemSet.class, "cardinalityMin");
		xstream.useAttributeFor(DataItemSet.class, "cardinalityMax");
		xstream.useAttributeFor(DataItemSet.class, "optional");
		xstream.useAttributeFor(Structure.class, "id");
		xstream.useAttributeFor(Structure.class, "name");
		xstream.useAttributeFor(Structure.class, "optional");
		xstream.useAttributeFor(StructureSet.class, "id");
		xstream.useAttributeFor(StructureSet.class, "cardinalityMin");
		xstream.useAttributeFor(StructureSet.class, "cardinalityMax");
		xstream.useAttributeFor(StructureSet.class, "optional");

		xstream.useAttributeFor(OutputDataItem.class, "id");
		xstream.useAttributeFor(OutputDataItem.class, "name");
		xstream.useAttributeFor(OutputDataItem.class, "domain");
		xstream.useAttributeFor(OutputDataItem.class, "optional");
		xstream.useAttributeFor(OutputDataItemSet.class, "cardinalityMin");
		xstream.useAttributeFor(OutputDataItemSet.class, "cardinalityMax");
		xstream.useAttributeFor(OutputDataItemSet.class, "optional");
		xstream.useAttributeFor(OutputStructure.class, "id");
		xstream.useAttributeFor(OutputStructure.class, "name");
		xstream.useAttributeFor(OutputStructure.class, "optional");
		xstream.useAttributeFor(OutputStructureSet.class, "id");
		xstream.useAttributeFor(OutputStructureSet.class, "name");
		xstream.useAttributeFor(OutputStructureSet.class, "optional");
		xstream.useAttributeFor(OutputStructureSet.class, "cardinalityMin");
		xstream.useAttributeFor(OutputStructureSet.class, "cardinalityMax");
		xstream.useAttributeFor(EnumeratedData.class, "id");
		xstream.useAttributeFor(EnumeratedData.class, "name");
		xstream.useAttributeFor(EnumeratedData.class, "optional");
		xstream.useAttributeFor(EnumeratedData.class, "cardinalityMin");
		xstream.useAttributeFor(EnumeratedData.class, "cardinalityMax");
		xstream.useAttributeFor(EnumeratedOption.class, "id");
		xstream.useAttributeFor(EnumeratedOption.class, "name");
		xstream.useAttributeFor(Text.class, "id");
		xstream.useAttributeFor(Text.class, "data");
		xstream.useAttributeFor(Text.class, "optional");
		xstream.useAttributeFor(Transition.class, "id");
		xstream.useAttributeFor(Transition.class, "target");
		xstream.useAttributeFor(Transition.class, "targetType");
		xstream.useAttributeFor(Transition.class, "noReturn");
		xstream.useAttributeFor(Transition.class, "condition");
		xstream.useAttributeFor(Transition.class, "option");
		xstream.useAttributeFor(TransitionFromSet.class, "number");
		xstream.useAttributeFor(ORDataEntry.class, "id");
		xstream.useAttributeFor(XORDataEntry.class, "id");
		xstream.useAttributeFor(OptionalDataItem.class, "id");
		xstream.useAttributeFor(OutputDataItemSet.class, "id");

		// Eu coloquei este:
		xstream.addImplicitCollection(UID.class, "setUIDCalls");

		xstream.addImplicitCollection(UID.class, "setStates");
		xstream.addImplicitCollection(UID.class, "listPreConditions");
		xstream.addImplicitCollection(UID.class, "listPosConditions");
		xstream.addImplicitCollection(UID.class, "listTextualNotes");
		// xstream.addImplicitCollection(UID.class, "setTransitions");
		xstream.addImplicitCollection(AbstractState.class, "listElements");
		xstream.addImplicitCollection(AbstractState.class,
				"listOutgoingTransitions");
		xstream.addImplicitCollection(DataEntry.class, "element");
		xstream.addImplicitCollection(DataOutput.class, "element");
		xstream.addImplicitCollection(OutputStructure.class,
				"listOutgoingTransitions");
		xstream.addImplicitCollection(OutputDataItem.class,
				"listOutgoingTransitions");
		xstream.addImplicitCollection(OutputStructureSet.class,
				"listOutgoingTransitions");
		xstream.addImplicitCollection(OutputDataItemSet.class,
				"listOutgoingTransitions");
		xstream.addImplicitCollection(Structure.class,
				"listDataItemsAndStructures");
		xstream.addImplicitCollection(EnumeratedData.class,
				"listEnumeratedOptions");
		xstream.addImplicitCollection(FacadeConstructorUID.class, "setUIDs");
	}

}